package com.hwg.shiliupro.utils;



import com.hwg.shiliupro.po.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;

public class JwtUtils {
    // token过期时间
    public static final long EXPIRE = 1000 * 60 * 60 * 24;  //一天
    // 秘钥 (盐)
    public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO";

    //生成token字符串的方法
    public static String getJwtToken(String id, User user){
        String JwtToken = Jwts.builder()
                //token的第一部分：头  设置一些信息  例如 HS256对称算法
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")

                //token的第二部分 载荷
                .setSubject("guli-user")
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))//过期时间

                //设置token主体部分 ，存储用户信息  还可以存储更多的其他信息
                .claim("id", id)
                .claim("user", user)

                //token的第三部分 签名 使用
                .signWith(SignatureAlgorithm.HS256, APP_SECRET)
                .compact();
        return JwtToken;
    }

    /**
     * 直接传参是字符串的token 来判断token是否存在与有效
     * @param jwtToken
     * @return
     */
    public static boolean checkToken(String jwtToken) {
        //token是否存在
        if(StringUtils.isEmpty(jwtToken)) {
            return false;
        }
        //token的合法性校验
        try {
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 通过HttpServletRequest的request 来判断token是否存在与有效
     * @param request
     * @return
     */
    public static boolean checkToken(HttpServletRequest request) {
        try {
            String jwtToken = request.getHeader("token");
            if(ObjectUtils.isEmpty(jwtToken)) {
                return false;
            }
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 根据token字符串获取当前登录的用户的id
     * @param request
     * @return
     */
    public static String getMemberIdByJwtToken(HttpServletRequest request) {
        String jwtToken = request.getHeader("Authorization");
        if(ObjectUtils.isEmpty(jwtToken)) {
            return "";  //调用者使用StringUtils进行判断  如果为空字符串 可知token校验失败
        }
        //StringUtils.isEmpty(null) = true
        //StringUtils.isEmpty("") = true
        //StringUtils.isEmpty(" ") = false
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        Claims claims = claimsJws.getBody();
        return (String)claims.get("id");
    }

    /**
     * 根据token字符串获取当前登录的用户的user对象
     * @param request
     * @return
     */
    public static Map getUserByJwtToken(HttpServletRequest request) {
        //Map userByJwtToken = JwtUtils.getUserByJwtToken(request);
        //System.out.println(userByJwtToken.get("id")); 存储在token里的user对象是可以拿到的，只不过是map的形式
        //要获取对象的具体值 可以通过map.get(key) key是对象的属性名
        //log.info("从token里获取的Map：{}",JwtUtils.getUserByJwtToken(request));
        String jwtToken = request.getHeader("Authorization");
        if(ObjectUtils.isEmpty(jwtToken)) {
            return null;
        }
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        Claims claims = claimsJws.getBody();
        Map map = (Map) claims.get("user");
        return map;
    }

}
